package com.ssish.eoms.util.ftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;




public class FtpUtil {
	
	private static Logger logger=Logger.getLogger(FtpUtil.class);
	
	private static FTPClient ftpClient =null;
	private String server;
	private int port;
	private String userName;
	private String userPassword;
	
	
	public FtpUtil() {
	}

	public FtpUtil(String server, int port, String userName, String userPassword) {
		this.server = server;
		this.port = port;
		this.userName = userName;
		this.userPassword = userPassword;
	}

	//private static FTPClientPool FTPClientPool ;
	
	/**
	 * 获取ftp连接
	 * @param f
	 * @return
	 * @throws Exception
	 */
	public static boolean connectFtp(Ftp f) throws Exception{
		ftpClient=new FTPClient();
		boolean flag=false;
		int reply;
		if (f.getPort()==null) {
			ftpClient.connect(f.getIpAddr(),21);
		}else{
			ftpClient.connect(f.getIpAddr(),f.getPort());
		}
		ftpClient.login(f.getUserName(), f.getPwd());
		ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
		reply = ftpClient.getReplyCode();      
	    if (!FTPReply.isPositiveCompletion(reply)) {      
	    	ftpClient.disconnect();      
	          return flag;      
	    } 
	    //
	    flag =ftpClient.changeWorkingDirectory(f.getPath());      
	    //flag = true;      
	    return flag;
	}
	
	/**
	 * 关闭ftp连接
	 */
	public static void closeFtp(){
		if (ftpClient!=null && ftpClient.isConnected()) {
			try {
				ftpClient.logout();
				ftpClient.disconnect();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * ftp上传文件
	 * @param f
	 * @throws Exception
	 */
	public static void upload(File f) throws Exception{
		if (f.isDirectory()) {
			ftpClient.makeDirectory(f.getName());
			ftpClient.changeWorkingDirectory(f.getName());
			String[] files=f.list();
			for(String fstr : files){
				File file1=new File(f.getPath()+"/"+fstr);
				if (file1.isDirectory()) {
					upload(file1);
					ftpClient.changeToParentDirectory();
				}else{
					File file2=new File(f.getPath()+"/"+fstr);
					FileInputStream input=new FileInputStream(file2);
					ftpClient.storeFile(file2.getName(),input);
					input.close();
				}
			}
		}else{
			File file2=new File(f.getPath());
			FileInputStream input=new FileInputStream(file2);
			ftpClient.storeFile(file2.getName(),input);
			input.close();
		}
	}
	
	/**
	 * 下载链接配置
	 * @param f
	 * @param localBaseDir 本地目录
	 * @param remoteBaseDir 远程目录
	 * @throws Exception
	 */
	public static void startDown(Ftp f,String localBaseDir,String remoteBaseDir ) throws Exception{
		if (FtpUtil.connectFtp(f)) {//登录成功
			
	        try { 
	            FTPFile[] files = null; 
	            boolean changedir = ftpClient.changeWorkingDirectory(remoteBaseDir); 
	            if (changedir) { 
	            	ftpClient.setControlEncoding("GBK"); 
	                files = ftpClient.listFiles(); 
	                for (int i = 0; i < files.length; i++) { 
	                    try{ 
	                        downloadFile(files[i], localBaseDir, remoteBaseDir); 
	                    }catch(Exception e){ 
	                    	logger.error(e); 
	                    	logger.error("<"+files[i].getName()+">下载失败"); 
	                    } 
	                } 
	            } 
	        } catch (Exception e) { 
	        	logger.error(e); 
	        	logger.error("下载过程中出现异常"); 
	        } 
		}else{
			logger.error("链接失败！");
		}
		
	}
	
	
	/** 
     * 
     * 下载FTP文件 
     * 当你需要下载FTP文件的时候，调用此方法 
     * 根据<b>获取的文件名，本地地址，远程地址</b>进行下载 
     * 
     * @param ftpFile 
     * @param relativeLocalPath 
     * @param relativeRemotePath 
     */ 
    private  static void downloadFile(FTPFile ftpFile, String relativeLocalPath,String relativeRemotePath) { 
        if (ftpFile.isFile()) {
            if (ftpFile.getName().indexOf("?") == -1) { 
                OutputStream outputStream = null; 
                try { 
                    File locaFile= new File(relativeLocalPath+ ftpFile.getName()); 
                    //判断文件是否存在，存在则返回 
                    if(locaFile.exists()){ 
                        return; 
                    }else{ 
                        outputStream = new FileOutputStream(relativeLocalPath+ ftpFile.getName()); 
                        ftpClient.retrieveFile(ftpFile.getName(), outputStream); 
                        outputStream.flush(); 
                        outputStream.close(); 
                    } 
                } catch (Exception e) { 
                    logger.error(e);
                } finally { 
                    try { 
                        if (outputStream != null){ 
                            outputStream.close(); 
                        }
                    } catch (IOException e) { 
                       logger.error("输出文件流异常"); 
                    } 
                } 
            } 
        } else { 
            String newlocalRelatePath = relativeLocalPath + ftpFile.getName(); 
            String newRemote = new String(relativeRemotePath+ ftpFile.getName().toString()); 
            File fl = new File(newlocalRelatePath); 
            if (!fl.exists()) { 
                fl.mkdirs(); 
            } 
            try { 
                newlocalRelatePath = newlocalRelatePath + '/'; 
                newRemote = newRemote + "/"; 
                String currentWorkDir = ftpFile.getName().toString(); 
                boolean changedir = ftpClient.changeWorkingDirectory(currentWorkDir); 
                if (changedir) { 
                    FTPFile[] files = null; 
                    files = ftpClient.listFiles(); 
                    for (int i = 0; i < files.length; i++) { 
                        downloadFile(files[i], newlocalRelatePath, newRemote); 
                    } 
                } 
                if (changedir){
                	ftpClient.changeToParentDirectory(); 
                } 
            } catch (Exception e) { 
                logger.error(e);
            } 
        } 
    } 
    
    //创建目录
    public boolean makeDirectory(String path) throws IOException {
        return ftpClient.makeDirectory(path);
    }
    
    /**
    *
    * @param path 上传到ftp服务器哪个路径下     
    * @return
    * @throws Exception
    */
   public void connect(String path) throws Exception {
	   ftpClient.changeWorkingDirectory(path);
   }

	
	/*public static void main(String[] args) throws Exception{  
			Ftp f=new Ftp();
			f.setIpAddr("114.55.39.153");
			f.setUserName("ftpadmin");
			f.setPwd("ssinanyan2016");
			boolean falg=FtpUtil.connectFtp(f);
			if(falg){
				System.out.println("登录成功");
			}else{
				System.out.println("登录失败");
			}
			
			//File file = new File("F:/test/com/test/Testng.java");  
			//FtpUtil.upload(file);//把文件上传在ftp上
			FtpUtil.startDown(f, "E:/",  "/xxtest");//下载ftp文件测试
			//System.out.println("ok");
	      
	   }  */
   
   
   public static void main(String[] args) {  
       FtpUtil f = new FtpUtil("114.55.39.153", 21, "ftpadmin", "ssinanyan2016");
       /*//本地文件目录和文件名 
       String localDirectoryAndFileName=""; 
      //上传后的文件名 
       String ftpFileName=""; 
       //FTP目录如:/path1/pathb2/,如果目录不存在回自动创建目录 
       String ftpDirectory="../ftpadmin/policy/";
       try {  
           if (f.open()) {  
        	   FTPFile[] flist=f.getFileList("/home/ftpadmin/policy/34922/fktzs");
        	   for (FTPFile ftpFile : flist) {
				System.out.println(ftpFile.getName());
        	   }
        	   f.close();  
           }  
       } catch (Exception e) {  
 
           e.printStackTrace();  
       }*/
       
    try {
    	OutputStream os=new FileOutputStream("D:/aaa.png");
    	 if (f.open()) { 
    		 ftpClient.retrieveFile("/home/ftpadmin/policy/34922/fktzs/fktzs.png", os);
    	 }
		os.flush();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
   }  
 
 
   /** 
    * 链接到服务器 
    *  
    * @return 
    * @throws Exception 
    */  
   public boolean open() {  
       if (ftpClient != null && ftpClient.isConnected()) {  
           return true;  
       }  
       try {  
           ftpClient = new FTPClient();  
           // 连接  
           ftpClient.connect(this.server, this.port);  
           ftpClient.login(this.userName, this.userPassword);  
           // 检测连接是否成功  
           int reply = ftpClient.getReplyCode();  
           if (!FTPReply.isPositiveCompletion(reply)) {  
               this.close();  
               System.err.println("FTP server refused connection.");  
               System.exit(1);  
           }  
           System.out.println("open FTP success:" + this.server+";port:"+this.port + ";name:"  
                   + this.userName + ";pwd:" + this.userPassword);  
           ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE); // 设置上传模式.binally  
                                                               // or ascii  
           return true;  
       } catch (Exception ex) {  
           // 关闭  
           this.close();  
           ex.printStackTrace();  
           return false;  
       }  
 
   }  
 
   private boolean cd(String dir) throws IOException {  
       if (ftpClient.changeWorkingDirectory(dir)) {  
           return true;  
       } else {  
           return false;  
       }  
   }  
 
   /** 
    * 获取目录下所有的文件名称 
    *  
    * @param filePath 
    * @return 
    * @throws IOException 
    */  
 
   public FTPFile[] getFileList(String filePath) throws IOException {  
       FTPFile[] list = ftpClient.listFiles(filePath);  
       return list;  
 
   }
   
   public void getFile(String filePath,OutputStream outputStream){  
	    try {
	    	ftpClient.retrieveFile(filePath, outputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}  
   }
 
   /** 
    * 循环将设置工作目录 
    */  
   public boolean changeDir(String ftpPath) {  
       if (!ftpClient.isConnected()) {  
           return false;  
       }  
       try {  
 
           // 将路径中的斜杠统一  
           char[] chars = ftpPath.toCharArray();  
           StringBuffer sbStr = new StringBuffer(256);  
           for (int i = 0; i < chars.length; i++) {  
 
               if ('\\' == chars[i]) {  
                   sbStr.append('/');  
               } else {  
                   sbStr.append(chars[i]);  
               }  
           }  
           ftpPath = sbStr.toString();  
           // System.out.println("ftpPath"+ftpPath);  
 
           if (ftpPath.indexOf('/') == -1) {  
               // 只有一层目录  
               // System.out.println("change"+ftpPath);  
               ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(),  
                       "iso-8859-1"));  
           } else {  
               // 多层目录循环创建  
               String[] paths = ftpPath.split("/");  
               // String pathTemp = "";  
               for (int i = 0; i < paths.length; i++) {  
                   // System.out.println("change "+paths[i]);  
                   ftpClient.changeWorkingDirectory(new String(paths[i]  
                           .getBytes(), "iso-8859-1"));  
               }  
           }  
 
           return true;  
       } catch (Exception e) {  
           e.printStackTrace();  
           return false;  
       }  
   }  
 
   /** 
    * 循环创建目录，并且创建完目录后，设置工作目录为当前创建的目录下 
    */  
   public boolean mkDir(String ftpPath) {  
       if (!ftpClient.isConnected()) {  
           return false;  
       }  
       try {  
 
           // 将路径中的斜杠统一  
           char[] chars = ftpPath.toCharArray();  
           StringBuffer sbStr = new StringBuffer(256);  
           for (int i = 0; i < chars.length; i++) {  
 
               if ('\\' == chars[i]) {  
                   sbStr.append('/');  
               } else {  
                   sbStr.append(chars[i]);  
               }  
           }  
           ftpPath = sbStr.toString();  
           System.out.println("ftpPath" + ftpPath);  
 
           if (ftpPath.indexOf('/') == -1) {  
               // 只有一层目录  
                 
               ftpClient.makeDirectory(new String(ftpPath.getBytes(),  
                       "iso-8859-1"));  
               ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(),  
                       "iso-8859-1"));  
           } else {  
               // 多层目录循环创建  
               String[] paths = ftpPath.split("/");  
               // String pathTemp = "";  
               for (int i = 0; i < paths.length; i++) {  
                 
                   ftpClient.makeDirectory(new String(paths[i].getBytes(),  
                           "iso-8859-1"));  
                   ftpClient.changeWorkingDirectory(new String(paths[i]  
                           .getBytes(), "iso-8859-1"));  
               }  
           }  
 
           return true;  
       } catch (Exception e) {  
           e.printStackTrace();  
           return false;  
       }  
   }  
 
   /** 
    * 上传文件到FTP服务器 
    *  
    * @param localPathAndFileName 
    *            本地文件目录和文件名 
    * @param ftpFileName 
    *            上传后的文件名 
    * @param ftpDirectory 
    *            FTP目录如:/path1/pathb2/,如果目录不存在回自动创建目录 
    * @throws Exception 
    */  
   public boolean put(MultipartFile file,String localDirectoryAndFileName, String ftpFileName,  
           String ftpDirectory) {  
       if (!ftpClient.isConnected()) {  
           return false;  
       }  
       boolean flag = false;  
       if (ftpClient != null) {  
           File srcFile = new File(localDirectoryAndFileName);  
           FileInputStream fis = null; 
           InputStream inStream=null;
           try {  
               //fis = new FileInputStream(srcFile); 
        	   inStream=file.getInputStream();
               // 创建目录  
               this.mkDir(ftpDirectory);  
               ftpClient.setBufferSize(1024);  
               //ftpClient.setControlEncoding("UTF-8");  
               // 设置文件类型（二进制）  
               ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
               // 上传   FTP协议里面，规定文件名编码为iso-8859-1，所以目录名或文件名需要转码。
               flag = ftpClient.storeFile(new String(ftpFileName.getBytes(),  
                       "iso-8859-1"), inStream);               
              // flag = ftpClient.storeFile(ftpFileName, inStream); 
               
               inStream.close();
           } catch (Exception e) {  
               this.close();  
               e.printStackTrace();  
               return false;  
           } 
       }  
 
       System.out.println("success put file " + localDirectoryAndFileName  
               + " to " + ftpDirectory + ftpFileName);  
       return flag;  
   }  
 
   /** 
    * 从FTP服务器上下载文件并返回下载文件长度 
    *  
    * @param ftpDirectoryAndFileName 
    * @param localDirectoryAndFileName 
    * @return 
    * @throws Exception 
    */  
   public long get(String ftpDirectoryAndFileName,String localDirectoryAndFileName) {  
 
       long result = 0;  
       if (!ftpClient.isConnected()) {  
           return 0;  
       }  
       ftpClient.enterLocalPassiveMode();   
       try {  
           // 将路径中的斜杠统一  
           char[] chars = ftpDirectoryAndFileName.toCharArray();  
           StringBuffer sbStr = new StringBuffer(256);  
           for (int i = 0; i < chars.length; i++) {  
 
               if ('\\' == chars[i]) {  
                   sbStr.append('/');  
               } else {  
                   sbStr.append(chars[i]);  
               }  
           }  
           ftpDirectoryAndFileName = sbStr.toString();  
           String filePath = ftpDirectoryAndFileName.substring(0,ftpDirectoryAndFileName.lastIndexOf("/"));  
           String fileName = ftpDirectoryAndFileName.substring(ftpDirectoryAndFileName.lastIndexOf("/") + 1);  
           this.changeDir(filePath);  
           ftpClient.retrieveFile( new String(fileName.getBytes(),"iso-8859-1"),   
           new FileOutputStream(localDirectoryAndFileName)); // download  
           System.out.print(ftpClient.getReplyString()); // check result  
 
       } catch (IOException e) {  
           e.printStackTrace();  
       }  
       System.out.println("Success get file" + ftpDirectoryAndFileName + " from " + localDirectoryAndFileName);  
       return result;  
   }  
 
   /** 
    * 返回FTP目录下的文件列表 
    *  
    * @param ftpDirectory 
    * @return 
    */  
   public List getFileNameList(String ftpDirectory) {  
       List list = new ArrayList();  
       // if (!open())  
       // return list;  
       // try {  
       // DataInputStream dis = new DataInputStream(ftpClient  
       // .nameList(ftpDirectory));  
       // String filename = "";  
       // while ((filename = dis.readLine()) != null) {  
       // list.add(filename);  
       // }  
       // } catch (Exception e) {  
       // e.printStackTrace();  
       // }  
       return list;  
   }  
 
   /** 
    * 删除FTP上的文件 
    *  
    * @param ftpDirAndFileName 
    */  
   public boolean deleteFile(String ftpDirAndFileName) {  
       if (!ftpClient.isConnected()) {  
           return false;  
       }  
       //Todo  
       return true;  
   }  
 
   /** 
    * 删除FTP目录 
    *  
    * @param ftpDirectory 
    */  
   public boolean deleteDirectory(String ftpDirectory) {  
       if (!ftpClient.isConnected()) {  
           return false;  
       }  
       //ToDo  
       return true;  
   }  
 
   /** 
    * 关闭链接 
    */  
   public void close() {  
        try {  
        if (ftpClient != null && ftpClient.isConnected())  
            ftpClient.disconnect();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("Close Server Success :"+this.server+";port:"+this.port);  
   }  
 
   public FTPClient getFtpClient() {  
       return ftpClient;  
   }  
 
   public void setFtpClient(FTPClient ftpClient) {  
 
       this.ftpClient = ftpClient;  
   }  
	
}
